import java.util.ArrayList;
import java.util.List;

public class BattleshipModel {
	private ArrayList<String> p1_used_cells = new ArrayList<String>();
	private ArrayList<String> p2_used_cells = new ArrayList<String>();
	private ArrayList<String> p1_ship_cells = new ArrayList<String>();
	private ArrayList<String> p2_ship_cells = new ArrayList<String>();
	private Ship p1_air = new AircraftCarrier();
	private Ship p1_bat = new Battleship();
	private Ship p1_cru = new Cruiser();
	private Ship p1_sub = new Submarine();
	private Ship p1_des = new Destroyer();
	private Ship p2_air = new AircraftCarrier();
	private Ship p2_bat = new Battleship();
	private Ship p2_cru = new Cruiser();
	private Ship p2_sub = new Submarine();
	private Ship p2_des = new Destroyer();
	
	
	//adds ship cells to the corresponding ship, only hassle being ships of len 3
	//however, code is ugly will need to tune it
	private void addShipCells(Boolean turn, ArrayList<String> array, int ship_len) {
		if (turn) {
			for (String s : array) {
				if (ship_len==5)
					p1_air.cells.add(s);
				if (ship_len==4)
					p1_bat.cells.add(s);
				if (ship_len==3) {
					if (p1_sub.cells.size() != 0) {
						p1_cru.cells.add(s);
					}
					else {
						p1_sub.cells.add(s);
					}
				}
				if (ship_len==2)
					p1_des.cells.add(s);
			}
		}
		else {
			for (String s : array) {
				if (ship_len==5)
					p2_air.cells.add(s);
				if (ship_len==4)
					p2_bat.cells.add(s);
				if (ship_len==3) {
					if (p2_sub.cells.size() != 0) {
						p2_cru.cells.add(s);
					}
					else {
						p2_sub.cells.add(s);
					}
				}
				if (ship_len==2)
					p2_des.cells.add(s);
			}
		}
	}

	// first print to the label "Player 1 place your aircraft carrier"
	// Click a button, actionListener gives (x,y) coordinate for it
	// Now need a method to map/highlight the possible locations
	public ArrayList<String> getEndpoints(Boolean p1_turn, String startpoint, int shipCount) {
		ArrayList<String> validPoints = new ArrayList<String>();
		int x = 0;
		int y = 0;
		if (startpoint.length() > 2 && startpoint.charAt(2) == '0') {
			x = Character.getNumericValue(startpoint.charAt(0)) - 9;
			y = 10;
		}else {
			x = Character.getNumericValue(startpoint.charAt(0)) - 9;
			y = Character.getNumericValue(startpoint.charAt(1));
		}
		
		int len = shipCount;
		System.out.println(x+" "+y+" "+len);
		if (p1_turn) { 
			// the VERTICAL case
			if (!(x + len - 1 > ButtonGrid.SIZE)) {
				boolean occupied = false;
				for (int i = x + len - 1; i > x; i--) {
					String spot = (char)(i+64) + Integer.toString(y);
					System.out.println("Vertical spots:" + spot);
					occupied = p1_ship_cells.contains(spot);
					if (occupied)
						break;
					// whether or not these cells matter, it's possible they matter!
				}
				if (!occupied) {
					// in the case they do matter, add'em to validPoints
					validPoints.add(Integer.toString(x+len-1)+Integer.toString(y));
				}
			}
			// the HORI-F'ing_ZONTAL case
			System.out.println(y+" "+len);
			if (!(y + len - 1> ButtonGrid.SIZE)) {
				boolean occupied = false;
				System.out.println(y+" "+len);
				for (int i = y + len - 1; i > y; i--) {
					String spot = (char)(x+64) + Integer.toString(i);
					System.out.println("Horizontal spots:" + spot);
					occupied = p1_ship_cells.contains(spot);
					if (occupied)
						break;
				}
				System.out.println(y+" "+len);
				if (!occupied) {
					validPoints.add(Integer.toString(x)+Integer.toString(y+len-1));
				}
				System.out.println(y+" "+len);
			}

		}
		else {
			// the VERTICAL case
			if (!(x + len - 1 > ButtonGrid.SIZE)) {
				boolean occupied = false;
				for (int i = x + len -1; i > x; i--) {
					String spot = (char)(i+64) + Integer.toString(y);
					System.out.println("Vertical spots:" + spot);
					occupied = p2_ship_cells.contains(spot);
					if (occupied)
						break;
					// whether or not these cells matter, it's possible they matter!
				}
				if (!occupied) {
					// in the case they do matter, add'em to validPoints
					validPoints.add(Integer.toString(x+len-1)+Integer.toString(y));
				}
			}
			// the HORI-F'ing_ZONTAL case
			System.out.println(y+" "+len);
			if (!(y + len - 1> ButtonGrid.SIZE)) {
				boolean occupied = false;
				System.out.println(y+" "+len);
				for (int i = y + len - 1; i > y; i--) {
					String spot = (char)(x+64) + Integer.toString(i);
					System.out.println("Horizontal spots:" + spot);
					occupied = p2_ship_cells.contains(spot);
					if (occupied)
						break;
				}
				System.out.println(y+" "+len);
				if (!occupied) {
					validPoints.add(Integer.toString(x)+Integer.toString(y+len-1));
				}
				System.out.println(y+" "+len);
			}
		}
		for (String s:validPoints) {
			System.out.println("Valid: " + s);
		}
		return validPoints;
		// these valid points should be highlighted by the VIEW
	}

	// Much like Rosi's deploy method, this method occurs after the
	// actionListener detects
	// that the client clicked a valid endpoint from getEndpoints
	// I suppose what's passed in is a single endpoint from validPoints
	public void placeShip(Boolean p1_turn, String start, String end, int shipCount) {
		char x_start = (char) (start.charAt(0));
		int y_start = Character.getNumericValue(start.charAt(1));
		char x_end = (char) (end.charAt(0));
		int y_end = 0;
		System.out.println("Start is: " + start +"\nEnd is: " +end + "\nstart.length "+start.length());
		if (start.length() > 2) {
			y_start =  10;
		} else {
			y_start = Character.getNumericValue(start.charAt(1));
		}
		if (end.length() > 2) {
			y_end =  10;
		} else {
			y_end = Character.getNumericValue(end.charAt(1));
		}
		ArrayList<String> shipCells = new ArrayList<String>();
		System.out.println("Place Ship Info: "+x_start+y_start+" , "+x_end+y_end);
		if (p1_turn) {
			// vertical values
			System.out.println("y_start " + y_start+"\ny_end "+y_end);
			if (y_start == y_end) {
				for (int i = x_start; i < x_end + 1; i++) {
					String s = (char)i + Integer.toString(y_start);
					p1_ship_cells.add(s);
					shipCells.add(s);
					System.out.println("Adding to p1 cells (vertical): " + s);
				}
			}
			// horizontal values
			System.out.println("x_start "+x_start+"\nx_end "+x_end);
			if (x_start == x_end) {
				for (int i = y_start; i < y_end + 1; i++) {
					String s = (char)x_start + Integer.toString(i);
					p1_ship_cells.add(s);
					shipCells.add(s);
					System.out.println("Adding to p1 cells (horizontal): " + s);
				}
			}
			
		}
		else {
			if (y_start == y_end) {
				for (int i = x_start; i < x_end+1; i++) {
					String s = (char)i + Integer.toString(y_start);
					p2_ship_cells.add(s);
					shipCells.add(s);
				}
			}
			// vertical values
			if (x_start == x_end) {
				for (int i = y_start; i < y_end+1; i++) {
					String s = (char)x_start + Integer.toString(i);
					p2_ship_cells.add(s);
					shipCells.add(s);
				}
			}
		}
		addShipCells(p1_turn,shipCells,shipCount);
	}
	
	public Boolean isValidPlacement (Boolean p1_turn, String clicked_cell) {
		boolean answer = false;
		if (p1_turn) {
			if (!p1_ship_cells.contains(clicked_cell)) {
				answer = true;
			}
		}
		else {
			if (!p2_ship_cells.contains(clicked_cell)) {
				answer = true;
			}
		}
		return answer;
	}

	public Boolean isValidAttack (Boolean p1_turn, String clicked_cell) {
		boolean answer = false;
		if (p1_turn) {
			if (!p1_used_cells.contains(clicked_cell)) {
				answer = true;
			}
		}
		else {
			if (!p2_used_cells.contains(clicked_cell)) {
				answer = true;
			}
		}
		return answer;
	}
	// Adds attacked cell to respective players used cell arrays
	public void addUsedCell(Boolean p1_turn, String clicked_cell) {
		if (p1_turn) {
			p1_used_cells.add(clicked_cell);
		}
		else {
			p2_used_cells.add(clicked_cell);
		}
	}

	// Cross references the current players attack cell with the opposing players ship cells to see if they're attack is a hit
	public boolean isHit(Boolean p1_turn, String clicked_cell) {
		boolean answer = false;
		if (p1_turn) {
			if (p2_ship_cells.contains(clicked_cell)) {
				answer = true;
			}
		}
		else {
			if (p1_ship_cells.contains(clicked_cell)) {
				answer = true;
			}
		}
		return answer;
	}

	public boolean isSunk(Boolean p1_turn, String clicked_cell) {
		// TODO Auto-generated method stub
				return false;
	}

	// Function that checks each ship array to see if they are all empty and returns true if they are indicating the game is over 
	public boolean isGameOver(Boolean p1_turn) {
		boolean answer = false;
		if (p1_turn) {
			//if (p1_air.isEmpty() && p1_bat.isEmpty() && p1_cru.isEmpty() && p1_des.isEmpty() && p1_sub.isEmpty()) {
			if (p1_ship_cells.isEmpty()) {
				answer = true;	
			}
		}
		else {
			//if (p2_air.isEmpty() && p2_bat.isEmpty() && p2_cru.isEmpty() && p2_des.isEmpty() && p2_sub.isEmpty()) {
			if (p2_ship_cells.isEmpty()) {
				answer = true;
			}
		}
		return answer;
	}
	
	public ArrayList<String> getUsedCells(Boolean turn) {
		if (turn) {
			return p1_used_cells;
		} else {
			return p2_used_cells;
		}
	}
	public ArrayList<String> getShipCells(Boolean turn) {
		if (turn) {
			return p1_ship_cells;
		} else {
			return p2_ship_cells;
		}
	}

}
